{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "1c53af79-6e54-4239-a73a-5bb06282fff3",
   "metadata": {},
   "source": [
    "# KNN"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9b6441d0-3b7b-42c6-9b50-b4dee4fe1867",
   "metadata": {},
   "source": [
    "### KNN模型的结果\n",
    "KNN算法不需要模型训练，所以没有什么结果可以查看\n",
    "\n",
    "### KNN模型的方法\n",
    "- fit(X,y)：输入数据集X和y对模型进行训练\n",
    "- predict(X)：输入数据集X，返回目标变量y的预测标签\n",
    "- predict_proba(X)：输入数据集X，返回目标变量y每一个类别的概率\n",
    "- score(X,y)：输入数据集X和y，返回模型预测结果的正确率（accuracy)\n",
    "\n",
    "### KNN模型代码示例"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fa03795c-aa15-47f6-bc2b-ffad710884e5",
   "metadata": {},
   "source": [
    "### Step1:使用sklearn自带的iris数据集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "10c77add-0517-4722-b0a8-9bdf32cafe89",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn import datasets\n",
    "# 导入sklearn自带的iris数据集\n",
    "iris = datasets.load_iris()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "7a0bf700-855a-4ace-88c8-0aa7e448b6c1",
   "metadata": {
    "collapsed": true,
    "jupyter": {
     "outputs_hidden": true
    },
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "sklearn.utils._bunch.Bunch"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(iris)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85db3431-d20b-4623-93fb-5feebe03f8dc",
   "metadata": {},
   "source": [
    "### Step2:拆分成训练集和测试集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "3d1adca7-38fd-4bac-90b3-d089178ea8fe",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "X_train,X_test,y_train,y_test=train_test_split(iris.data,iris.target,test_size=0.4,random_state=305)  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "c1b31246-7f92-4005-a97f-4b9c5b6ef2e2",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[7.2, 3. , 5.8, 1.6],\n",
       "       [5.5, 2.4, 3.7, 1. ],\n",
       "       [6.9, 3.1, 5.1, 2.3],\n",
       "       [6.2, 2.8, 4.8, 1.8],\n",
       "       [5. , 2.3, 3.3, 1. ],\n",
       "       [5.7, 3.8, 1.7, 0.3],\n",
       "       [6.7, 3.1, 5.6, 2.4],\n",
       "       [5.6, 3. , 4.5, 1.5],\n",
       "       [6.7, 3.1, 4.7, 1.5],\n",
       "       [5.1, 3.4, 1.5, 0.2],\n",
       "       [5. , 3.5, 1.3, 0.3],\n",
       "       [5. , 2. , 3.5, 1. ],\n",
       "       [5.5, 2.6, 4.4, 1.2],\n",
       "       [5. , 3.3, 1.4, 0.2],\n",
       "       [5.4, 3.9, 1.7, 0.4],\n",
       "       [5.2, 4.1, 1.5, 0.1],\n",
       "       [5.1, 3.8, 1.5, 0.3],\n",
       "       [5.1, 3.5, 1.4, 0.2],\n",
       "       [6. , 3. , 4.8, 1.8],\n",
       "       [5.7, 2.8, 4.1, 1.3],\n",
       "       [5.4, 3. , 4.5, 1.5],\n",
       "       [5.9, 3. , 5.1, 1.8],\n",
       "       [6.4, 2.8, 5.6, 2.1],\n",
       "       [7.7, 3.8, 6.7, 2.2],\n",
       "       [5.8, 2.8, 5.1, 2.4],\n",
       "       [5.6, 2.9, 3.6, 1.3],\n",
       "       [4.6, 3.4, 1.4, 0.3],\n",
       "       [6.5, 3. , 5.8, 2.2],\n",
       "       [4.9, 3.6, 1.4, 0.1],\n",
       "       [5.5, 2.3, 4. , 1.3],\n",
       "       [5.8, 2.6, 4. , 1.2],\n",
       "       [5.4, 3.4, 1.7, 0.2],\n",
       "       [6.5, 3. , 5.2, 2. ],\n",
       "       [6.2, 2.9, 4.3, 1.3],\n",
       "       [4.8, 3.4, 1.9, 0.2],\n",
       "       [6. , 2.2, 4. , 1. ],\n",
       "       [6.4, 3.2, 4.5, 1.5],\n",
       "       [6.3, 3.4, 5.6, 2.4],\n",
       "       [6.5, 3.2, 5.1, 2. ],\n",
       "       [4.9, 3. , 1.4, 0.2],\n",
       "       [6.8, 3. , 5.5, 2.1],\n",
       "       [5.3, 3.7, 1.5, 0.2],\n",
       "       [6.7, 3.3, 5.7, 2.1],\n",
       "       [7.7, 3. , 6.1, 2.3],\n",
       "       [4.6, 3.6, 1. , 0.2],\n",
       "       [5.7, 4.4, 1.5, 0.4],\n",
       "       [5.9, 3.2, 4.8, 1.8],\n",
       "       [5. , 3.6, 1.4, 0.2],\n",
       "       [6.7, 3. , 5.2, 2.3],\n",
       "       [6.1, 2.9, 4.7, 1.4],\n",
       "       [6.4, 3.2, 5.3, 2.3],\n",
       "       [5.5, 4.2, 1.4, 0.2],\n",
       "       [6. , 2.9, 4.5, 1.5],\n",
       "       [5.5, 3.5, 1.3, 0.2],\n",
       "       [5.6, 2.8, 4.9, 2. ],\n",
       "       [6.3, 3.3, 4.7, 1.6],\n",
       "       [6.1, 3. , 4.6, 1.4],\n",
       "       [6.9, 3.1, 5.4, 2.1],\n",
       "       [5.1, 3.8, 1.9, 0.4],\n",
       "       [5.8, 2.7, 5.1, 1.9],\n",
       "       [5.1, 3.8, 1.6, 0.2],\n",
       "       [4.9, 2.4, 3.3, 1. ],\n",
       "       [5. , 3.5, 1.6, 0.6],\n",
       "       [6.1, 2.6, 5.6, 1.4],\n",
       "       [6.7, 3.3, 5.7, 2.5],\n",
       "       [6.1, 2.8, 4.7, 1.2],\n",
       "       [4.6, 3.1, 1.5, 0.2],\n",
       "       [5.9, 3. , 4.2, 1.5],\n",
       "       [6.2, 3.4, 5.4, 2.3],\n",
       "       [5.6, 2.5, 3.9, 1.1],\n",
       "       [6.4, 3.1, 5.5, 1.8],\n",
       "       [4.3, 3. , 1.1, 0.1],\n",
       "       [6.7, 3.1, 4.4, 1.4],\n",
       "       [4.4, 3.2, 1.3, 0.2],\n",
       "       [5. , 3.4, 1.5, 0.2],\n",
       "       [6.3, 2.8, 5.1, 1.5],\n",
       "       [5. , 3. , 1.6, 0.2],\n",
       "       [4.8, 3.1, 1.6, 0.2],\n",
       "       [6.4, 2.7, 5.3, 1.9],\n",
       "       [6.5, 2.8, 4.6, 1.5],\n",
       "       [6.3, 3.3, 6. , 2.5],\n",
       "       [4.9, 3.1, 1.5, 0.2],\n",
       "       [4.8, 3. , 1.4, 0.3],\n",
       "       [6.1, 3. , 4.9, 1.8],\n",
       "       [5.6, 2.7, 4.2, 1.3],\n",
       "       [4.5, 2.3, 1.3, 0.3],\n",
       "       [5.1, 2.5, 3. , 1.1],\n",
       "       [6.2, 2.2, 4.5, 1.5],\n",
       "       [6.7, 2.5, 5.8, 1.8],\n",
       "       [5.2, 2.7, 3.9, 1.4]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "62d37240-3942-41b2-91f0-9768134ecc19",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(90, 4)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "32073c1d-b657-4346-b82a-4197fe4b71b4",
   "metadata": {},
   "source": [
    "### Step3:模型训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "c03fc6fc-1630-4cb7-ad85-4a69489223c7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-1 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: black;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-1 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-1 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: block;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-1 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-1 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-1 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 1ex;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-1 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>KNeighborsClassifier()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow fitted\">&nbsp;&nbsp;KNeighborsClassifier<a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.5/modules/generated/sklearn.neighbors.KNeighborsClassifier.html\">?<span>Documentation for KNeighborsClassifier</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></label><div class=\"sk-toggleable__content fitted\"><pre>KNeighborsClassifier()</pre></div> </div></div></div></div>"
      ],
      "text/plain": [
       "KNeighborsClassifier()"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "\n",
    "# 实例化模型并训练\n",
    "model = KNeighborsClassifier()\n",
    "model.fit(X_train,y_train)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e88ee5cb-a976-4dfd-8a52-24d4df9f723f",
   "metadata": {},
   "source": [
    "### Step4：模型评估\n",
    "针对分类模型，有很多评估方法，常用的有\n",
    "- 误分类矩阵 confusion_matrix\n",
    "- 分类报告 classification_report\n",
    "- ROC曲线和AUC值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "266bc14f-a901-439c-b89c-4612aefb51ab",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.95\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       1.00      1.00      1.00        19\n",
      "           1       0.95      0.90      0.93        21\n",
      "           2       0.90      0.95      0.93        20\n",
      "\n",
      "    accuracy                           0.95        60\n",
      "   macro avg       0.95      0.95      0.95        60\n",
      "weighted avg       0.95      0.95      0.95        60\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# 方法1：直接使用模型的score方法计算正确率\n",
    "print(model.score(X_test,y_test))\n",
    "\n",
    "# 方法2：使用sklearn.metrics下的classification_report方法\n",
    "# 先对测试集进行预测\n",
    "y_pred = model.predict(X_test) #预测类别标签\n",
    "y_pred_prob = model.predict_proba(X_test) #预测类别概率\n",
    "\n",
    "# 分类评估报告classification_report\n",
    "from sklearn.metrics import classification_report\n",
    "print(classification_report(y_test,y_pred))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0985d23-e317-47f6-abc5-9537268467fe",
   "metadata": {},
   "source": [
    "precision ( 精确度)：正确预测为正的，占全部预测为正的比例。\n",
    "\n",
    "recall（召回率）：正确预测为正的，占全部实际为正的比例。\n",
    "\n",
    "f1-score (f1值)：精确率和召回率的调和平均数。\n",
    "\n",
    "support （各分类样本的数量或测试集样本的总数量）。\n",
    "\n",
    "macro avg (宏平均值)：所有标签结果的平均值。\n",
    "\n",
    "weighted avg（加权平均值）：所有标签结果的加权平均值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "941b9173-3b1b-43cd-bde9-6f09ecf28269",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 2 0 2 1 1 2 1 0 1 2 2 0 2 0 1 2 0 1 1 2 2 1 2 0 0 2 1 0 1 1 1 2 2 1 1 0\n",
      " 0 0 2 1 1 2 2 1 2 1 2 0 1 0 2 0 2 0 0 0 0 2 1]\n",
      "[[1.  0.  0. ]\n",
      " [0.  0.  1. ]\n",
      " [1.  0.  0. ]\n",
      " [0.  0.  1. ]\n",
      " [0.  1.  0. ]\n",
      " [0.  1.  0. ]\n",
      " [0.  0.4 0.6]\n",
      " [0.  1.  0. ]\n",
      " [1.  0.  0. ]\n",
      " [0.  0.6 0.4]]\n"
     ]
    }
   ],
   "source": [
    "# 查看预测结果\n",
    "print(y_pred)\n",
    "print(y_pred_prob[:10])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6f170c30-4f35-453e-8c14-9ff652ea549b",
   "metadata": {},
   "source": [
    "### KNN模型的决策边界"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "43f8ef72-821f-4e05-823f-02e66bc61a3c",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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ITpDt19zI4QQQghxKkluhBBCCBFXJLkRQgghRFyR5EYIIYQQcUWSm070yCOPoJTi3nvvjXYowo+f//znKKVafY0YMSLaYYkgjhw5wle/+lWys7NJTExk7NixrFmzJtphCT8GDBjQ5u9LKcXdd98d7dCEH16vl5/+9KcMHDiQxMREBg8ezMMPPxxS36buoNtXKI4Vq1ev5oknnmDcuHHRDkUEMXr0aBYtWtTyvdUqfwKxqqKigpkzZ3L++efz/vvvk5OTw65du8jMzIx2aMKP1atX4/V6W74vKiri4osvZt68eVGMSgTy6KOP8vjjj/PPf/6T0aNHs2bNGm6//XbS09O55557oh3eGZNX9k5QW1vLzTffzN///nd++ctfRjscEYTVaiU/Pz/aYYgQPProoxQWFvLMM8+0XDZw4MAoRiSCycnJafX9I488wuDBg5k1a1aUIhLBLF++nDlz5nDllVcCvpm3l19+mVWrVkU5ss4hp6U6wd13382VV17JRRddFO1QRDt27dpFnz59GDRoEDfffHOrIpEitrz99ttMnjyZefPmkZuby8SJE/n73/8e7bBECFwuFy+88AJ33HFHpzYoFp1nxowZLF68mJ07dwKwceNGli1bxuWXXx7lyDqHzNycoVdeeYV169axevXqaIci2jF16lSeffZZhg8fTnFxMQ899BDnnnsuRUVFpKamRjs8cZq9e/fy+OOP8/3vf58f//jHrF69mnvuuQe73c6tt94a7fBEEG+++SaVlZXcdttt0Q5FBPA///M/VFdXM2LECCwWC16vl1/96lfcfPPN0Q6tU0hycwYOHTrE9773PRYuXEhCQkK0wxHtOPUTybhx45g6dSr9+/fn3//+N3feeWcUIxP+mKbJ5MmT+fWvfw3AxIkTKSoq4m9/+5skNzHuH//4B5dffjl9+vSJdigigH//+9+8+OKLvPTSS4wePZoNGzZw77330qdPn7j4+5Lk5gysXbuWsrIyJk2a1HKZ1+vl008/5c9//jNOpxOLxRLFCEUwGRkZDBs2rFXzVhE7evfuzahRo1pdNnLkSF577bUoRSRCceDAARYtWsTrr78e7VBEED/4wQ/4n//5H2688UYAxo4dy4EDB5g/f74kNz3dhRdeyObNm1tddvvttzNixAh+9KMfSWIT42pra9mzZw9f+9rXoh2K8GPmzJns2LGj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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 使用花萼的长度和宽度绘制散点图，并绘出分类决策边界  \n",
    "import numpy as np  \n",
    "import matplotlib.pyplot as plt  \n",
    "from matplotlib.colors import ListedColormap  \n",
    "from sklearn import datasets  \n",
    "from sklearn.neighbors import KNeighborsClassifier  \n",
    "%matplotlib inline\n",
    "\n",
    "# 为了作图方便，我们只选择花萼的长度和宽度作为X变量\n",
    "iris=datasets.load_iris( )  \n",
    "x=iris.data[:,:2]   #选择花萼的长度和宽度(前2个列）作为数据集x\n",
    "y=iris.target       #数据集y\n",
    "  \n",
    "# 计算花萼的长度和宽度的最大值和最小值（散点图的x坐标和y坐标的范围）\n",
    "x_min,x_max=x[:,0].min() -.5, x[:,0].max()+.5\n",
    "y_min, y_max=x[:,1].min()-.5, x[:,1].max()+.5\n",
    "\n",
    "# 自定义三个颜色映射\n",
    "cmap_light=ListedColormap(['#AAAAFF','#AAFFAA','#FFAAAA'])\n",
    "\n",
    "# 以0.02为间隔，在xy坐标轴的范围内画网格,形成171*231的网格矩阵\n",
    "h=.02\n",
    "xx,yy=np.meshgrid(np.arange(x_min,x_max,h),np.arange(y_min,y_max,h))  \n",
    "\n",
    "# 用数据集x和y构建逻辑回归模型\n",
    "knn=KNeighborsClassifier()  \n",
    "knn.fit(x,y)\n",
    "\n",
    "# 把xx和yy拉平变成171*231=39501个维度的向量，然后拼接在一起，变成一个39501*2的矩阵，作为数据集X，用模型对它进行类别预测\n",
    "Z=knn.predict(np.c_[xx.ravel(),yy.ravel()])\n",
    "\n",
    "# 把Z重新reshape为(171,231)\n",
    "Z=Z.reshape(xx.shape) \n",
    "\n",
    "# 用pcolormesh绘制决策边界：传入参数：网格数据xx,yy以及对应的类别预测结果Z，自定义颜色映射cmap_light，一个颜色区块内代表模型预测的一个类别\n",
    "plt.figure()\n",
    "plt.pcolormesh(xx,yy,Z,cmap=cmap_light)\n",
    "\n",
    "# 设置图形的一些基本外观参数\n",
    "plt.xlabel('sepal length')\n",
    "plt.ylabel('sepal width')\n",
    "plt.scatter(x[:,0],x[:,1],c=y)\n",
    "plt.xlim(xx.min(), xx.max())\n",
    "plt.ylim(yy.min(),yy.max())\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "390638fa-f17c-45a1-ac37-eeefd6b40506",
   "metadata": {},
   "source": [
    "# homework"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "08c04cae-3153-4bdf-836a-957ce35d9f09",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "data = pd.read_csv('./wine.txt',header=None)\n",
    "X=data.iloc[:,1:].values\n",
    "y=data.iloc[:,0].values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "03e2e869-197c-4254-b6fb-fb03f9a7d711",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=123456)  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "3914dcfa-277c-477a-a7d4-d66786a07529",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-2 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: black;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-2 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-2 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-2 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: block;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-2 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-2 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-2 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-2 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-2 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-2 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-2 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-2 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 1ex;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-2 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-2 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-2\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>KNeighborsClassifier()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-2\" type=\"checkbox\" checked><label for=\"sk-estimator-id-2\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow fitted\">&nbsp;&nbsp;KNeighborsClassifier<a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.5/modules/generated/sklearn.neighbors.KNeighborsClassifier.html\">?<span>Documentation for KNeighborsClassifier</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></label><div class=\"sk-toggleable__content fitted\"><pre>KNeighborsClassifier()</pre></div> </div></div></div></div>"
      ],
      "text/plain": [
       "KNeighborsClassifier()"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "\n",
    "# 实例化模型并训练\n",
    "model = KNeighborsClassifier()\n",
    "model.fit(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "3af7c8fe-35de-4246-987b-75c5a3e9ddb3",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.8333333333333334\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           1       0.92      1.00      0.96        11\n",
      "           2       0.80      0.94      0.86        17\n",
      "           3       0.75      0.38      0.50         8\n",
      "\n",
      "    accuracy                           0.83        36\n",
      "   macro avg       0.82      0.77      0.77        36\n",
      "weighted avg       0.82      0.83      0.81        36\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# 方法1：直接使用模型的score方法计算正确率\n",
    "print(model.score(X_test,y_test))\n",
    "\n",
    "# 方法2：使用sklearn.metrics下的classification_report方法\n",
    "# 先对测试集进行预测\n",
    "y_pred = model.predict(X_test) #预测类别标签\n",
    "y_pred_prob = model.predict_proba(X_test) #预测类别概率\n",
    "\n",
    "# 分类评估报告classification_report\n",
    "from sklearn.metrics import classification_report\n",
    "print(classification_report(y_test,y_pred))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bb77e2c5-f805-4df4-ac4e-973ad79568ac",
   "metadata": {},
   "source": [
    "# 归一化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "f1aed5dd-d55a-4389-8dbf-9e45d249e32e",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import MinMaxScaler\n",
    "\n",
    "scaler = MinMaxScaler()\n",
    "normalized_data = scaler.fit_transform(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "8c239ee8-751e-4bc8-b512-dec6df2eccfb",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "X_train,X_test,y_train,y_test=train_test_split(normalized_data,y,test_size=0.4,random_state=123456) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "e4cb525a-af73-42d6-9ff7-fcedf166a858",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-3 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: black;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-3 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-3 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-3 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-3 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-3 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: block;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-3 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-3 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-3 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-3 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-3 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-3 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-3 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-3 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-3 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-3 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 1ex;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-3 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-3 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-3 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-3\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>KNeighborsClassifier()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-3\" type=\"checkbox\" checked><label for=\"sk-estimator-id-3\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow fitted\">&nbsp;&nbsp;KNeighborsClassifier<a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.5/modules/generated/sklearn.neighbors.KNeighborsClassifier.html\">?<span>Documentation for KNeighborsClassifier</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></label><div class=\"sk-toggleable__content fitted\"><pre>KNeighborsClassifier()</pre></div> </div></div></div></div>"
      ],
      "text/plain": [
       "KNeighborsClassifier()"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "\n",
    "# 实例化模型并训练\n",
    "model = KNeighborsClassifier()\n",
    "model.fit(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "02cf0078-03ec-483a-8b0c-d91507989d4a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.9861111111111112\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           1       1.00      1.00      1.00        24\n",
      "           2       1.00      0.96      0.98        28\n",
      "           3       0.95      1.00      0.98        20\n",
      "\n",
      "    accuracy                           0.99        72\n",
      "   macro avg       0.98      0.99      0.99        72\n",
      "weighted avg       0.99      0.99      0.99        72\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# 方法1：直接使用模型的score方法计算正确率\n",
    "print(model.score(X_test,y_test))\n",
    "\n",
    "# 方法2：使用sklearn.metrics下的classification_report方法\n",
    "# 先对测试集进行预测\n",
    "y_pred = model.predict(X_test) #预测类别标签\n",
    "y_pred_prob = model.predict_proba(X_test) #预测类别概率\n",
    "\n",
    "# 分类评估报告classification_report\n",
    "from sklearn.metrics import classification_report\n",
    "print(classification_report(y_test,y_pred))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a523bef-fd99-419d-b219-8574cf964c6b",
   "metadata": {},
   "source": [
    "# pendigits"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "5649b51a-6a7c-4179-9272-7a1c688c3bce",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "data = pd.read_csv('./pendigits.txt',header=None)\n",
    "X_p=data.iloc[:,:-1].values\n",
    "y_p=data.iloc[:,-1].values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "4f681c60-b18e-410d-89ba-24b0f2f0f49c",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "X_train,X_test,y_train,y_test=train_test_split(X_p,y_p,test_size=0.4,random_state=123456)  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "11cabba6-caed-46c3-97a1-f4a775f4d57d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-4 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: black;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-4 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-4 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-4 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-4 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-4 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: block;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-4 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-4 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-4 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-4 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-4 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-4 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-4 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-4 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-4 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-4 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 1ex;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-4 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-4 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-4 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-4\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>KNeighborsClassifier()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-4\" type=\"checkbox\" checked><label for=\"sk-estimator-id-4\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow fitted\">&nbsp;&nbsp;KNeighborsClassifier<a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.5/modules/generated/sklearn.neighbors.KNeighborsClassifier.html\">?<span>Documentation for KNeighborsClassifier</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></label><div class=\"sk-toggleable__content fitted\"><pre>KNeighborsClassifier()</pre></div> </div></div></div></div>"
      ],
      "text/plain": [
       "KNeighborsClassifier()"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "\n",
    "# 实例化模型并训练\n",
    "model = KNeighborsClassifier()\n",
    "model.fit(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "17ecd6eb-f1bb-4169-857a-9461c55c5298",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.9916611074049366\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       1.00      0.99      1.00       312\n",
      "           1       1.00      0.97      0.98       314\n",
      "           2       0.98      1.00      0.99       297\n",
      "           3       0.97      0.99      0.98       306\n",
      "           4       0.99      1.00      1.00       294\n",
      "           5       0.99      0.99      0.99       303\n",
      "           6       1.00      1.00      1.00       287\n",
      "           7       0.99      1.00      0.99       297\n",
      "           8       1.00      0.99      0.99       293\n",
      "           9       1.00      0.99      0.99       295\n",
      "\n",
      "    accuracy                           0.99      2998\n",
      "   macro avg       0.99      0.99      0.99      2998\n",
      "weighted avg       0.99      0.99      0.99      2998\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# 方法1：直接使用模型的score方法计算正确率\n",
    "print(model.score(X_test,y_test))\n",
    "\n",
    "# 方法2：使用sklearn.metrics下的classification_report方法\n",
    "# 先对测试集进行预测\n",
    "y_pred = model.predict(X_test) #预测类别标签\n",
    "y_pred_prob = model.predict_proba(X_test) #预测类别概率\n",
    "\n",
    "# 分类评估报告classification_report\n",
    "from sklearn.metrics import classification_report\n",
    "print(classification_report(y_test,y_pred))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "444dff59-ee98-4fe4-b1c0-4d125666ba32",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.9916611074049366\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       1.00      0.99      1.00       312\n",
      "           1       1.00      0.97      0.98       314\n",
      "           2       0.98      1.00      0.99       297\n",
      "           3       0.97      0.99      0.98       306\n",
      "           4       0.99      1.00      1.00       294\n",
      "           5       0.99      0.99      0.99       303\n",
      "           6       1.00      1.00      1.00       287\n",
      "           7       0.99      1.00      0.99       297\n",
      "           8       1.00      0.99      0.99       293\n",
      "           9       1.00      0.99      0.99       295\n",
      "\n",
      "    accuracy                           0.99      2998\n",
      "   macro avg       0.99      0.99      0.99      2998\n",
      "weighted avg       0.99      0.99      0.99      2998\n",
      "\n"
     ]
    }
   ],
   "source": [
    "#归一化后重新建模分析\n",
    "from sklearn.preprocessing import MinMaxScaler\n",
    "\n",
    "scaler = MinMaxScaler()\n",
    "P_normalized_data = scaler.fit_transform(X_p)\n",
    "\n",
    "from sklearn.model_selection import train_test_split\n",
    "X_train,X_test,y_train,y_test=train_test_split(P_normalized_data,y_p,test_size=0.4,random_state=123456)\n",
    "\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "\n",
    "# 实例化模型并训练\n",
    "model = KNeighborsClassifier()\n",
    "model.fit(X_train,y_train)\n",
    "\n",
    "# 方法1：直接使用模型的score方法计算正确率\n",
    "print(model.score(X_test,y_test))\n",
    "\n",
    "# 方法2：使用sklearn.metrics下的classification_report方法\n",
    "# 先对测试集进行预测\n",
    "y_pred = model.predict(X_test) #预测类别标签\n",
    "y_pred_prob = model.predict_proba(X_test) #预测类别概率\n",
    "\n",
    "# 分类评估报告classification_report\n",
    "from sklearn.metrics import classification_report\n",
    "print(classification_report(y_test,y_pred))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6e6294b5-2914-45f8-9cb4-3bef2405207f",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
